package com.renovate.portal.fragments;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.Enumeration;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;

import android.app.Activity;
import android.app.Fragment;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.os.PowerManager;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;

import com.renovate.portal.R;
import com.renovate.portal.adapters.BootAnimListAdapter;
import com.renovate.portal.parse.XMLParser;
import com.renovate.portal.util.ConnectionDetector;
import com.renovate.portal.util.Helpers;
import com.renovate.portal.util.UnzipUtil;
import com.renovate.portal.util.XMLFormatUtil;
import com.htc.app.HtcProgressDialog;
import com.htc.widget.HtcAlertDialog;

public class BootAnimFragment extends Fragment implements OnClickListener,
		OnItemClickListener {
	Boolean isInternetPresent = false;
	ConnectionDetector cd;
	private HtcProgressDialog mProgressDialog;
	String unzipLocation = Environment.getExternalStorageDirectory()
			+ "/Renovate/Portal/BootAnim/";
	String zipFile = Environment.getExternalStorageDirectory()
			+ "/*.zip";
	Button button;
	ListView listView;
	List<XMLFormatUtil> newsview;
	BootAnimListAdapter listViewAdapter;
	String URL = "";
	
	Context mContext;

	public BootAnimFragment() {
	}

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		final Context contextThemeWrapper = new ContextThemeWrapper(getActivity(), R.style.IndicatorTheme);

	    // clone the inflater using the ContextThemeWrapper
	    LayoutInflater localInflater = inflater.cloneInContext(contextThemeWrapper);

	    // inflate the layout using the cloned inflater, not default inflater
		View view = localInflater.inflate(R.layout.page_list, container, false);
		URL = "http://www.renovate-themes.de/m8s6l/boot.xml";
		button = (Button) view.findViewById(R.id.button);
		listView = (ListView) view.findViewById(R.id.item_list);
		button.setOnClickListener(this);
		cd = new ConnectionDetector(getActivity());
		isInternetPresent = cd.isConnectingToInternet();
		if (isInternetPresent) {
			GetXMLTask task = new GetXMLTask(getActivity());
			SharedPreferences getPrefs = PreferenceManager
					.getDefaultSharedPreferences(getActivity());
			boolean bootanim_on_start = getPrefs
					.getBoolean("load_bootanim", true);
			if (bootanim_on_start == true)
				task.execute(URL);

		} else {
			Toast.makeText(getActivity(), R.string.connect_internet,
					Toast.LENGTH_LONG).show();
		}
		listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) {
				Object o = listView.getItemAtPosition(position);
				final XMLFormatUtil obj_itemDetails = (XMLFormatUtil) o;
				HtcAlertDialog.Builder alertDialog = new HtcAlertDialog.Builder(
						getActivity());

				alertDialog.setTitle(R.string.install);

				alertDialog.setMessage(obj_itemDetails.getHeadline() + "\n\n"
						+ obj_itemDetails.getText());

				alertDialog.setPositiveButton(R.string.yes,
						new DialogInterface.OnClickListener() {
							@Override
							public void onClick(DialogInterface dialog,
									int which) {
								DownloadMapAsync mew = new DownloadMapAsync();
								mew.execute(obj_itemDetails.getDescription());
							}
						});
				alertDialog.setNegativeButton(R.string.no,
						new DialogInterface.OnClickListener() {
							@Override
							public void onClick(DialogInterface dialog,
									int which) {

								dialog.cancel();
							}
						});
				alertDialog.show();
			}

		});
		return view;

	}

	@Override
	public void onItemClick(AdapterView<?> parent, View view, int position,
			long id) {
		// TODO Auto-generated method stub

	}

	@Override
	public void onClick(View v) {
		if (isInternetPresent) {
			GetXMLTask task = new GetXMLTask(getActivity());
			task.execute(URL);
		} else {
			Toast.makeText(getActivity(), R.string.connect_internet,
					Toast.LENGTH_LONG).show();

		}

	}

	class DownloadMapAsync extends AsyncTask<String, String, String> {
		String result = "";

		@Override
		protected void onPreExecute() {
			super.onPreExecute();
			mProgressDialog = new HtcProgressDialog(getActivity());
			mProgressDialog.setTitle(getString(R.string.downloading));
			mProgressDialog.setMessage(getString(R.string.downloading_file));
			mProgressDialog
					.setProgressStyle(HtcProgressDialog.STYLE_HORIZONTAL);
			mProgressDialog.setCancelable(false);
			mProgressDialog.show();

		}

		@Override
		protected String doInBackground(String... aurl) {
			int count;

			try {

				URL url = new URL(aurl[0]);
				URLConnection conexion = url.openConnection();
				conexion.connect();
				int lenghtOfFile = conexion.getContentLength();
				InputStream input = new BufferedInputStream(url.openStream());

				OutputStream output = new FileOutputStream(zipFile);

				byte data[] = new byte[1024];
				long total = 0;

				while ((count = input.read(data)) != -1) {
					total += count;
					publishProgress("" + (int) ((total * 100) / lenghtOfFile));
					output.write(data, 0, count);
				}
				output.close();
				input.close();
				result = "true";

			} catch (Exception e) {

				result = "false";
			}
			return null;

		}

		@Override
		protected void onProgressUpdate(String... progress) {
			Log.d("ANDRO_ASYNC", progress[0]);
			mProgressDialog.setProgress(Integer.parseInt(progress[0]));
		}

		@Override
		protected void onPostExecute(String unused) {
			mProgressDialog.dismiss();
			if (result.equalsIgnoreCase("true")) {
				Toast.makeText(getActivity(), R.string.download_complete,
						Toast.LENGTH_LONG).show();

				try {
					unzip();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			} else {

			}
		}
	}

	public void unzip() throws IOException {
		mProgressDialog = new HtcProgressDialog(getActivity());
		mProgressDialog.setMessage(getString(R.string.processing));
		mProgressDialog.setProgressStyle(HtcProgressDialog.STYLE_SPINNER);
		mProgressDialog.setCancelable(false);
		mProgressDialog.show();
		new UnZipTask().execute(zipFile, unzipLocation);
	}

	private class UnZipTask extends AsyncTask<String, Void, Boolean> {
		@SuppressWarnings("rawtypes")
		@Override
		protected Boolean doInBackground(String... params) {
			String filePath = params[0];
			String destinationPath = params[1];

			File archive = new File(filePath);
			try {

				ZipFile zipfile = new ZipFile(archive);
				for (Enumeration e = zipfile.entries(); e.hasMoreElements();) {
					ZipEntry entry = (ZipEntry) e.nextElement();
					unzipEntry(zipfile, entry, destinationPath);
				}

				UnzipUtil d = new UnzipUtil(zipFile, unzipLocation);
				d.unzip();

			} catch (Exception e) {

				return false;
			}

			return true;
		}

		@Override
		protected void onPostExecute(Boolean result) {
			mProgressDialog.dismiss();
			HtcAlertDialog.Builder alertDialog = new HtcAlertDialog.Builder(
					getActivity());

			alertDialog.setTitle(R.string.download_complete);

			alertDialog.setMessage(R.string.install_dialog);

			alertDialog.setPositiveButton(R.string.install_now,
					new DialogInterface.OnClickListener() {
				@Override
				public void onClick(DialogInterface dialog, int which) {
					
					// check out the method at the bottom which has the code for rebooting to recovery
					rebootRecovery();
				}
			});
			alertDialog.setNegativeButton(R.string.install_later,
					new DialogInterface.OnClickListener() {
						@Override
						public void onClick(DialogInterface dialog, int which) {
							Toast.makeText(getActivity(), R.string.install_manual,
									Toast.LENGTH_LONG).show();}
					});
			alertDialog.show();

		}

		private void unzipEntry(ZipFile zipfile, ZipEntry entry,
				String outputDir) throws IOException {

			if (entry.isDirectory()) {
				createDir(new File(outputDir, entry.getName()));
				return;
			}

			File outputFile = new File(outputDir, entry.getName());
			if (!outputFile.getParentFile().exists()) {
				createDir(outputFile.getParentFile());
			}
			BufferedInputStream inputStream = new BufferedInputStream(
					zipfile.getInputStream(entry));
			BufferedOutputStream outputStream = new BufferedOutputStream(
					new FileOutputStream(outputFile));

			try {

			} finally {
				outputStream.flush();
				outputStream.close();
				inputStream.close();

			}
		}

		private void createDir(File dir) {
			if (dir.exists()) {
				return;
			}
			if (!dir.mkdirs()) {
				throw new RuntimeException("Can not create dir " + dir);
			}
		}
	}

	private class GetXMLTask extends AsyncTask<String, Void, List<XMLFormatUtil>> {
		@Override
		protected void onPreExecute() {
			super.onPreExecute();
			mProgressDialog = new HtcProgressDialog(getActivity());
			mProgressDialog.setMessage(getString(R.string.retrieve_item));
			mProgressDialog.setProgressStyle(HtcProgressDialog.STYLE_SPINNER);
			mProgressDialog.setCancelable(false);
			mProgressDialog.show();
		}

		private Activity context;

		public GetXMLTask(Activity context) {
			this.context = context;
		}

		@Override
		protected void onPostExecute(List<XMLFormatUtil> newsview) {
			listViewAdapter = new BootAnimListAdapter(context, newsview);
			listView.setAdapter(listViewAdapter);
			mProgressDialog.dismiss();
		}

		private String getXmlFromUrl(String urlString) {
			String xml = null;

			try {
				DefaultHttpClient httpClient = new DefaultHttpClient();
				HttpGet httpGet = new HttpGet(URL);

				HttpResponse httpResponse = httpClient.execute(httpGet);
				HttpEntity httpEntity = httpResponse.getEntity();
				xml = EntityUtils.toString(httpEntity, HTTP.UTF_8);

			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			} catch (ClientProtocolException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
			return xml;
		}

		@Override
		protected List<XMLFormatUtil> doInBackground(String... urls) {
			List<XMLFormatUtil> newsview = null;
			String xml = null;
			for (String url : urls) {
				xml = getXmlFromUrl(url);

				InputStream stream = new ByteArrayInputStream(xml.getBytes());
				newsview = XMLParser.parse(stream);

				for (XMLFormatUtil newsviewsingle : newsview) {
					String imageURL = newsviewsingle.getImageURL();
					Bitmap bitmap = null;
					BitmapFactory.Options bmOptions = new BitmapFactory.Options();
					bmOptions.inSampleSize = 1;

					try {
						bitmap = BitmapFactory
								.decodeStream(new URL(imageURL).openStream(),
										null, bmOptions);
					} catch (MalformedURLException e) {
						e.printStackTrace();
					} catch (IOException e) {
						e.printStackTrace();
					}
					newsviewsingle.setImageBitmap(bitmap);
				}
			}
			return newsview;
		}
	}
	
	/*
	 *  We use this method to reboot into recovery
	 */
	void rebootRecovery() { 
		((PowerManager) getActivity().getSystemService(Context.POWER_SERVICE))
		.reboot("recovery");
        
    }
}
